// M3U8 Crawler 后台脚本

// 存储检测到的M3U8文件
let m3u8Files = [];

// 监听web请求，查找M3U8文件
chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    // 检查URL是否包含M3U8相关内容
    if (details.url.includes('.m3u8') || details.url.includes('playlist.m3u') || 
        details.url.includes('stream.m3u')) {
      console.log('⏰ ~ details.url:', details.url);
      
      // 检查URL是否已存在（去重）
      const existingIndex = m3u8Files.findIndex(file => file.url === details.url);
      const timestamp = new Date().toISOString();
      
      if (existingIndex !== -1) {
        // URL已存在，更新时间戳但保留其他信息
        console.log('URL已存在，更新时间戳:', details.url);
        m3u8Files[existingIndex].timestamp = timestamp;
        
        // 存储到Chrome存储
        chrome.storage.local.set({ m3u8Files: m3u8Files }, () => {
          console.log('M3U8文件已更新:', m3u8Files[existingIndex]);
        });
        
        // 通知content script更新
        chrome.tabs.sendMessage(details.tabId, {
          type: 'M3U8_UPDATED',
          data: m3u8Files[existingIndex]
        });
      } else {
        // URL不存在，生成临时ID（使用简单哈希避免异步问题）
        const tempId = simpleHash(details.url);
        const m3u8Info = {
          url: details.url,
          tabId: details.tabId,
          timestamp: timestamp,
          id: tempId
        };
        
        // 添加到列表
        m3u8Files.push(m3u8Info);
        
        // 存储到Chrome存储
        chrome.storage.local.set({ m3u8Files: m3u8Files }, () => {
          console.log('M3U8文件已保存:', m3u8Info);
        });
        
        // 通知content script有新的M3U8文件被发现
        chrome.tabs.sendMessage(details.tabId, {
          type: 'NEW_M3U8_FOUND',
          data: m3u8Info
        });
      }
    }
  },
  {
    urls: ['<all_urls>'],
    types: ['xmlhttprequest', 'media']
  }
);

// 监听来自popup或content script的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  switch (message.type) {
    case 'GET_M3U8_FILES':
      sendResponse({ m3u8Files: m3u8Files });
      break;
    case 'CLEAR_M3U8_FILES':
      m3u8Files = [];
      chrome.storage.local.remove('m3u8Files', () => {
        sendResponse({ success: true });
      });
      break;
    case 'SAVE_M3U8':
      // 保存M3U8信息到API
      saveM3U8(message.url, (error, result) => {
        if (error) {
          sendResponse({ success: false, error: error.message });
        } else {
          sendResponse(result);
        }
      });
      return true; // 异步响应
  }
});

// 当扩展安装时初始化存储
chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.local.set({ m3u8Files: [] });
  console.log('M3U8 Crawler 已安装并初始化');
});

// 基于URL生成hash值
function generateHash(url) {
    // 使用SHA-256算法生成hash值
    return new Promise((resolve, reject) => {
      if (typeof crypto !== 'undefined' && crypto.subtle) {
        const encoder = new TextEncoder();
        const data = encoder.encode(url);
        
        crypto.subtle.digest('SHA-256', data)
          .then(hashBuffer => {
            // 转换为十六进制字符串
            const hashArray = Array.from(new Uint8Array(hashBuffer));
            const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
            // 截取前32位作为ID
            resolve(hashHex.substring(0, 32));
          })
          .catch(error => {
            console.error('生成hash失败:', error);
            // 降级到简单的hash方法
            resolve(simpleHash(url));
          });
      } else {
        // 如果浏览器不支持crypto API，使用简单的hash方法
        resolve(simpleHash(url));
      }
    });
  }
  
// 简单的hash生成方法（降级方案）
function simpleHash(str) {
    let hash = 0;
    if (str.length === 0) return hash.toString(16).padStart(32, '0');
    
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // 转换为32位整数
    }
    
    // 转换为十六进制并确保长度为32
    let hex = Math.abs(hash).toString(16);
    while (hex.length < 32) {
      hex = '0' + hex;
    }
    return hex.substring(0, 32);
  }

// 生成随机标题（基于时间和时长）
function generateRandomTitle(durationSeconds) {
  const now = new Date();
  const dateStr = now.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  }).replace(/\//g, '-');
  
  const timeStr = now.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit'
  }).replace(/:/g, '');
  
  // 生成随机形容词
  const adjectives = ['精彩', '高清', '流畅', '优质', '超清', '热播', '精选', '独家'];
  const randomAdj = adjectives[Math.floor(Math.random() * adjectives.length)];
  
  // 生成随机名词
  const nouns = ['视频', '电影', '剧集', '节目', '内容', '片段', '直播', '短片'];
  const randomNoun = nouns[Math.floor(Math.random() * nouns.length)];
  
  // 格式化时长
  const hours = Math.floor(durationSeconds / 3600);
  const minutes = Math.floor((durationSeconds % 3600) / 60);
  const seconds = durationSeconds % 60;
  let durationStr = '';
  
  if (hours > 0) {
    durationStr = `${hours}小时${minutes}分`;
  } else if (minutes > 0) {
    durationStr = `${minutes}分${seconds}秒`;
  } else {
    durationStr = `${seconds}秒`;
  }
  
  return `${dateStr}_${timeStr}_${randomAdj}${randomNoun}_${durationStr}`;
}

// 解析M3U8文件内容，计算时长（秒）
function parseM3U8Duration(m3u8Content) {
  const extinfRegex = /#EXTINF:([\d.]+)/g;
  let totalDuration = 0;
  let match;
  
  // 提取所有EXTINF标签中的时长并累加
  while ((match = extinfRegex.exec(m3u8Content)) !== null) {
    totalDuration += parseFloat(match[1]);
  }
  
  return Math.round(totalDuration);
}

// 获取M3U8文件时长
async function getM3U8Duration(m3u8Url) {
  try {
    const response = await fetch(m3u8Url);
    if (!response.ok) {
      throw new Error(`HTTP错误! 状态: ${response.status}`);
    }
    
    const content = await response.text();
    return parseM3U8Duration(content);
  } catch (error) {
    console.error('获取M3U8时长失败:', error);
    throw error;
  }
}

// 视频关键帧获取功能已移除

// 保存M3U8信息到API
  async function saveM3U8(url, callback) {
    try {
      console.log('开始保存M3U8:', url);
      
      // 1. 基于URL生成hash值
      console.log('步骤1: 基于URL生成hash值');
      const hashId = await generateHash(url);
      console.log('生成hashId:', hashId);
      
      // 2. 检查该ID是否已存在于数据库中
      console.log('步骤2: 检查ID是否已存在');
      try {
        const existsResponse = await fetch(`http://localhost:3000/api/videos?id=${hashId}`, {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json'
          }
        });
        
        const existsData = await existsResponse.json();
        
        // 如果ID已存在，则不保存
        if (existsData.exists || existsData.video) {
          console.log('ID已存在，不重复保存');
          if (callback) callback(null, {
            success: true,
            message: '该视频已存在，无需重复保存',
            exists: true,
            id: hashId
          });
          return;
        }
        console.log('ID不存在，可以保存');
      } catch (existsError) {
        console.warn('检查ID是否存在时出错:', existsError);
        // 如果检查失败，继续执行保存（容错处理）
      }
      
      // 3. 解析M3U8时长
      console.log('步骤3: 解析M3U8时长');
      const duration = await getM3U8Duration(url);
      console.log('获取到时长:', duration);
      
      // 4. 检查时长是否小于10秒
      if (duration < 10) {
        throw new Error('M3U8时长小于10秒，链接无效');
      }
      console.log('时长检查通过');
      
      // 5. 生成随机标题
      console.log('步骤4: 生成随机标题');
      const title = generateRandomTitle(duration);
      console.log('生成标题:', title);
      
      // 7. 准备数据结构
      console.log('步骤6: 准备数据结构');
      const videoData = {
        id: hashId,
        title: title,
        category: "2025102906",
        sourceUrl: url,
        coverUrl: '', // 封面图功能已移除
        description: "",
        durationSeconds: Math.round(duration)
      };
      
      // 7. 发送数据到API
      console.log('步骤5: 发送数据到API');
      try {
        const response = await fetch('http://localhost:3000/api/videos', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(videoData)
        });
        
        if (!response.ok) {
          throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
        }
        
        const result = await response.json();
        console.log('API响应成功:', result);
        
        // 8. 调用回调函数通知成功
        if (callback) callback(null, {
          success: true,
          message: '保存成功',
          data: result
        });
      } catch (apiError) {
        console.error('API请求失败:', apiError);
        // 如果API请求失败，提供更详细的错误信息
        if (callback) callback(new Error(`保存到API失败: ${apiError.message || '未知错误'}。请确保后端服务正在运行，并且URL正确。`));
      }
    } catch (error) {
      console.error('保存M3U8失败:', error);
      if (callback) callback(error);
    }
  }